package com.yuntoyun.fwcore.plug.tool;
/*
 * +----------------------------------------------------------------------
 * | @Author: codeavatar   @Year：2021
 * +----------------------------------------------------------------------
 * | @Email: codeavatar@aliyun.com
 * +----------------------------------------------------------------------
 */
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketAdapter;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketExtension;
import com.neovisionaries.ws.client.WebSocketFactory;
import com.yuntoyun.fwcore.config.FwAppConfig;
import com.yuntoyun.fwcore.util.FwLogUtil;

import java.io.IOException;

/**
 * WebSocket工具类
 */
public class FwWebSocketTool {

    private static final String TAG = "WEBSOCKET";

    private static final String SERVER = String.format("ws://%s:%d", FwAppConfig.WEBSOCKET_HOST,
            FwAppConfig.WEBSOCKET_PORT);
    private static final int CONNECTION_TIMEOUT = 5000;
    private static final int PING_INTERVAL = 5000;
    private static final int FRAME_QUEUE_SIZE = 5;

    private WebSocket webSocket = null;
    private WebSocketAdapter webSocketAdapter;
    private WebSocketState webSocketState;

    private static FwWebSocketTool singleton;

    public static FwWebSocketTool getSingleton() {
        if (singleton == null) {
            synchronized (FwWebSocketTool.class) {
                if (singleton == null) {
                    singleton = new FwWebSocketTool();
                }
            }
        }

        return singleton;
    }

    public void setWebSocketAdapter(WebSocketAdapter webSocketAdapter) {
        this.webSocketAdapter = webSocketAdapter;
    }

    public void initSocket() {
        try {
            if (null == webSocket) {
                FwLogUtil.info("WebSocket开始创建链接！");
                // Connect to the echo server.
                webSocket = connect();
            } else {
                FwLogUtil.info(String.format("WebSocket链接检测状态【%b】！", webSocket.isOpen()));
                if (!webSocket.isOpen()) {
                    webSocket = webSocket.recreate();
                    webSocket.connect();
                    FwLogUtil.info("WebSocket重新创建并链接！");
                }
            }
        } catch (IOException e) {
            FwLogUtil.error(TAG, e);
        } catch (WebSocketException e) {
            FwLogUtil.error(TAG, e);
        }
    }

    public void sendSocket(String msg) {
        if (null != webSocket && webSocket.isOpen()) {
            // Send the text to the server.
            webSocket.sendText(msg);
            webSocket.flush();
            FwLogUtil.info(String.format("WebSocket发送%s成功！", msg));
        }
    }

    public void sendClose() {
        if (null != webSocket && webSocket.isOpen()) {
            webSocket.sendClose();
        }
    }

    public void closeSocket() {
        if (null != webSocket) {
            webSocket.disconnect();
        }
    }

    /**
     * Connect to the server.
     */
    private WebSocket connect() throws IOException,
            WebSocketException {

        FwLogUtil.info(String.format("WebSocket服务地址%s！", SERVER));

        return new WebSocketFactory()
                .setConnectionTimeout(CONNECTION_TIMEOUT)
                .createSocket(SERVER)
                .addListener(webSocketAdapter)
//                .setPingInterval(PING_INTERVAL)
//                .setMissingCloseFrameAllowed(false)
//                .setFrameQueueSize(FRAME_QUEUE_SIZE)
                .addExtension(WebSocketExtension.PERMESSAGE_DEFLATE)
                .connect();
    }

    public void setWebSocketState(WebSocketState state) {
        this.webSocketState = state;
    }

    public WebSocketState getWebSocketState() {
        return this.webSocketState;
    }

    public enum WebSocketState {
        Connected, Timeout, Disconnected
    }
}
